package com.project.srtp.secure.util;

import com.project.srtp.secure.model.ComplexDfa;
import com.project.srtp.secure.model.DfaTransition;
import org.kie.dmn.feel.FEEL;
import org.kie.dmn.feel.lang.ast.BaseNode;
import org.kie.dmn.feel.lang.ast.InfixOpNode;
import org.kie.dmn.feel.lang.ast.UnaryTestNode;
import org.kie.dmn.feel.lang.impl.FEELImpl;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

public class FeelToDfaConverter {
    private static final String INITIAL_STATE = "q0";           // 初始状态
    private static final String VIOLATION_STATE = "q_violation";// 违规状态
    private static final String ACCEPT_STATE = "q_accept";      // 接受状态（合规）
    private static final FEEL FEEL_PARSER = FEEL.newInstance(); // FEEL解析器实例

    /**
     * 将 FEEL 表达式字符串转换为 ComplexDfa 对象。
     * 生成的 DFA 具有单一初始状态（q0）、单一违规状态和单一接受状态。
     *
     * @param feelExpression FEEL 表达式字符串
     * @return 该表达式对应的复杂有限自动机（ComplexDfa）
     */
    public static ComplexDfa convert(String feelExpression) {

        // 解析 FEEL 表达式得到抽象语法树 (AST)
        BaseNode ast = FeelAstUtil.parseExpression(feelExpression);

        // 创建 DFA 构建上下文
        DfaBuilderContext context = new DfaBuilderContext();

        // 从 AST 根节点递归构建 DFA，起始状态为 q0，接受状态为 q_accept
        buildFromNode(ast, INITIAL_STATE, ACCEPT_STATE, context);

        // 构建并返回最终的 ComplexDfa 对象
        return context.buildDfa();
    }

    /**
     * 递归辅助方法，遍历 AST 构建 DFA。
     *
     * @param node         当前处理的 AST 节点
     * @param currentState 当前 DFA 状态，从此状态发出新的转换
     * @param successState 条件满足时应跳转到的状态
     * @param context      构建 DFA 的上下文对象，存储状态和转换
     */
    private static void buildFromNode(BaseNode node, String currentState, String successState, DfaBuilderContext context) {
        // 处理逻辑运算符 'and' 和 'or'
        if (node instanceof InfixOpNode opNode) {
            BaseNode left = opNode.getLeft();
            BaseNode right = opNode.getRight();

            switch (opNode.getOperator()) {
                case AND:
                    // 对于 'and'，创建串联链路：current -> intermediate -> success
                    String intermediateState = context.newNextState();
                    buildFromNode(left, currentState, intermediateState, context);
                    buildFromNode(right, intermediateState, successState, context);
                    break;
                case OR:
                    // 对于 'or'，从当前状态并行分支到相同的成功状态
                    buildFromNode(left, currentState, successState, context);
                    buildFromNode(right, currentState, successState, context);
                    break;
                default:
                    // 其它中缀操作符（如算术）当作单个条件处理
                    addConditionTransition(node.getText(), currentState, successState, context);
                    break;
            }
        }
        // 处理逻辑非 'not'
        else if (node instanceof UnaryTestNode && ((UnaryTestNode) node).getOperator() == UnaryTestNode.UnaryOperator.NOT) {
            // 对于 'not(A)'，整体当作单个条件转换处理
            addConditionTransition(node.getText(), currentState, successState, context);
        }
        // 处理基本条件（比较、函数调用等）
        else {
            addConditionTransition(node.getText(), currentState, successState, context);
        }
    }

    /**
     * 添加一个条件转换。在此简化模型中，不显式添加“非”条件转到违规状态的转换，
     * 运行时合规检查器通常会推断若无有效转换即为违规。
     *
     * @param condition 条件字符串（输入符号）
     * @param fromState 转换起始状态
     * @param toState   条件满足时的目标状态
     * @param context   DFA 构建上下文
     */
    private static void addConditionTransition(String condition, String fromState, String toState, DfaBuilderContext context) {
        context.addTransition(fromState, condition, toState);
    }

    /**
     * 内部类，维护 DFA 构建时的状态集合、转换集合和状态编号生成。
     */
    private static class DfaBuilderContext {
        private final Set<String> states = new HashSet<>(Arrays.asList(INITIAL_STATE, VIOLATION_STATE, ACCEPT_STATE));
        private final List<DfaTransition> transitions = new ArrayList<>();
        private final AtomicInteger stateCounter = new AtomicInteger(1); // q0 已占用

        /**
         * 生成一个新的唯一状态名，如 q1, q2 ...
         *
         * @return 新状态名
         */
        String newNextState() {
            String state = "q" + stateCounter.getAndIncrement();
            states.add(state);
            return state;
        }

        /**
         * 添加状态转换
         *
         * @param from   起始状态
         * @param symbol 条件符号（输入）
         * @param to     目标状态
         */
        void addTransition(String from, String symbol, String to) {
            transitions.add(new DfaTransition(from, symbol, to));
        }

        /**
         * 构造最终 ComplexDfa 对象
         *
         * @return 构建好的 DFA
         */
        ComplexDfa buildDfa() {
            ComplexDfa dfa = new ComplexDfa();
            dfa.setInitialState(INITIAL_STATE);
            dfa.setStates(this.states);
            dfa.setViolationStates(new HashSet<>(Collections.singletonList(VIOLATION_STATE)));
            dfa.setTransitions(this.transitions);

            Map<String, String> metadata = new HashMap<>();
            metadata.put("acceptState", ACCEPT_STATE);
            dfa.setMetadata(metadata);

            return dfa;
        }
    }
}
